package ray.shader;

import java.util.ArrayList;
import java.util.List;

import ray.Intersection;
import ray.Ray;
import ray.RayTracer;
import ray.Scene;
import ray.Light;
import ray.math.Color;
import ray.math.Vector3;

public class Glazed extends Shader {
       
    protected double refractiveIndex;
    public void setRefractiveIndex(double refractiveIndex) { this.refractiveIndex = refractiveIndex; }
       
    protected Shader substrate;
    public void setSubstrate(Shader substrate) { this.substrate = substrate; }
       
    public Glazed() { }
       
    /**
     * Calculate the BRDF value for this material at the intersection described in record.
     * Returns the BRDF color in outColor.
     * @param outColor Space for the output color
     * @param scene The scene
     * @param lights The lights
     * @param toEye Vector pointing towards the eye
     * @param record The intersection record, which hold the location, normal, etc.
     * @param depth The depth of recursive calls.
     * @param contribution The contribution of the current ray.
     * @param internal You can ignore this for glazed.
     */
   
    @Override
    public void shade(Color outColor, Scene scene, ArrayList<Light> lights, Vector3 toEye, Intersection record, int depth, double contribution, boolean internal)
    {
        double dp = toEye.dot(record.normal);
        if (depth <= Shader.MAXDEPTH && contribution >= Shader.MINCONTRIBUTION && dp > 0)
        {
                double r0 = ((refractiveIndex - 1)*(refractiveIndex - 1)) / ((refractiveIndex + 1) * (refractiveIndex + 1));

                double myWeight = r0 + (1-r0)*Math.pow(1-dp, 5);
                myWeight = 1 - myWeight;
                substrate.shade(outColor, scene, lights, toEye, record, depth+1, contribution * myWeight, internal);
               
                Ray reflectionRay = new Ray(record.intersection, record.normal);
                reflectionRay.d.scale(2*dp);
                reflectionRay.d.sub(toEye);
                reflectionRay.d.normalize();
               
                reflectionRay.makeOffsetRay();
               
                Intersection eyeRecord = new Intersection();

                       
                       
                       
               
                //System.out.println("reflecting a ray. Depth: " + depth);
                        if (scene.getFirstIntersection(eyeRecord, reflectionRay))
                        {
                        reflectionRay.d.scale(-1); //should actually create a new variable, but this is more efficient
                               
                        eyeRecord.surface.getShader().shade(outColor, scene, lights, reflectionRay.d, eyeRecord, depth+1, contribution * (1-myWeight), false);
                        }
                        else
                        {
                                //there might be background color stuff going on here
                                outColor.r += 0.0 * (1 - myWeight);
                                outColor.g += 0.0 * (1 - myWeight);
                                outColor.b += 0.0 * (1 - myWeight);
                        }
        }
    }

}

